路由跟 URL 重寫的功能性略有不同。路由是將 Request 找到對應的服務,而 URL 重寫是為了推卸責任 XD轉送 Request。
本篇將介紹 ASP.NET Core 的 URL 重寫 (URL Rewrite)。
同步發佈至個人部落格:
John Wu's Blog - [鐵人賽 Day08] ASP.NET Core 2 系列 - URL 重寫 (URL Rewrite)
URL Rewriting Middleware 需要
Microsoft.AspNetCore.Rewrite
套件。
ASP.NET Core 2.0 以上版本,預設是參考Microsoft.AspNetCore.All
,已經包含Microsoft.AspNetCore.Rewrite
,所以不用再安裝。
URL 重寫功能是在 ASP.NET Core 1.1 之後的版本才有,如果是 ASP.NET Core 2.0 以前版本,可以透過 .NET Core CLI 在專案資料夾執行安裝指令:
dotnet add package Microsoft.AspNetCore.Rewrite
要使用 URL 重寫,在 Startup.cs 的 Configure
對 IApplicationBuilder
使用 UseRewriter
方法註冊 URL Rewriting Middleware:
Startup.cs
// ...
public class Startup
{
public void Configure(IApplicationBuilder app)
{
var rewrite = new RewriteOptions()
.AddRewrite("about.aspx", "home/about", skipRemainingRules: true)
.AddRedirect("first", "home/index");
app.UseRewriter(rewrite);
// ...
}
}
透過 RewriteOptions
建立 URL 重寫規則後,傳入給 URL Rewriting Middleware。
URL 重寫規則,主要有分兩種方式:
AddRewrite
就是 URL 重寫。AddRedirect
就是 URL 轉址。URL 重寫是屬於 Server 端的轉換事件,當 Client 端 Request 來的時候,發現原網址已經被換掉了,就會自動回傳新網址的內容。情境如下:
上例 AddRewrite
有用到三個參數,當 URL 符合 參數 1 時,就將 參數 2 路由的內容回傳給 Client。
而 參數 3 是用來加速 URL 匹配的參數,類似 switch 的 break。若將 skipRemainingRules
設為 true,當找到匹配條件,就不再繼續往下找符合其他 參數 1 的規則。
範例結果:
URL 重寫是屬於 Client 端的轉換事件,當 Client 端 Request 來的時候,發現原網址已經被換掉了,Server 會先回傳給 Client 告知新網址,再由 Client 重新 Request 新網址。情境如下:
AddRedirect
的使用方式類似 AddRewrite
,當 URL 符合 參數 1 時,就會回傳 參數 2 的 URL 給 Client。
URL 轉址預設都是回傳 HTTP Status Code 302,也可以在 參數 3 指定回傳的 HTTP Status Code。
通常轉址的 HTTP Status Code 都是用 301 或 302 ,URL 轉址對 "人" 的行為來說沒有什麼意義,反正就是幫忙從 A 轉到 B;主要差異是給 "搜尋引擎" 理解的。
Startup.cs
// ...
public class Startup
{
public void Configure(IApplicationBuilder app)
{
var rewrite = new RewriteOptions()
.AddRedirect("first", "home/index", 301);
app.UseRewriter(rewrite);
// ...
}
}
AddRewrite
及 AddRedirect
都支援正規表示式的使用,且能把來源的 URL 透過正規表示式變成參數,帶入新 URL。
範例程式:
Startup.cs
// ...
public class Startup
{
public void Configure(IApplicationBuilder app)
{
var rewrite = new RewriteOptions()
.AddRedirect("products.aspx?id=(\w+)", "prosucts/$1", 301);
.AddRedirect("api/(.*)/(.*)/(.*)", "api?p1=$1&p2=$2&p3=$3", 301);
app.UseRewriter(rewrite);
// ...
}
}
http://localhost:5000/products.aspx?id=p123
http://localhost:5000/products/p123
http://localhost:5000/api/first/second/third
http://localhost:5000/api?p1=first&p2=second&p3=third
透過正規表示式做 URL 轉址,對於網站新舊改版來說,非常好用。
URL Rewriting Middleware in ASP.NET Core
John大好,我在AddRedirect()裡的來源URL跟你一樣使用path?xxx=yyy ,server似乎無法解析?起頭的query string,
然後試著加入這段
app.UseMvc(routes =>
{
routes.MapRoute(
name: "querytemplate",
template: "{controller=Home}?id={aciton}"
);
build時出現
Innermost exception System.ArgumentException : The literal section '?id=' is invalid. Literal sections cannot contain the '?' character.
意思是asp.net core不支援這種形式嗎?
aciton 不能是 query srting 參數